PARSER_BEGIN(UcParser) 
  
import java.util.*;
import java.io.*;  

class UcParser {
  public static void main(String[] arg) 
  throws ParseException, IOException {
    if (arg.length != 1) {
        System.out.println("Usage: UcParse <input file name>");
        System.exit(0);
    }

    InputStream is = new FileInputStream(arg[0]);

    UcParser parser = new UcParser(is);
    program();
    System.out.println("parsed");
    //Node tree = program();
    //tree.print("");

  }
}

PARSER_END(UcParser)


// More tokens here!
TOKEN : {<#DIGIT : ["0"-"9"]>}
TOKEN : {<#LETTER: ["a"-"z","A"-"Z","_"]>}
TOKEN : {<#CHARACTER: [" ","!","\"","#","$","%","&","'","(",")","*","+",",","-",".","/","0"-"9",":",";","<","=",">","?","@","A"-"Z","[","\\","]","^","_","`","a"-"z","{","|","}","~"]>}
TOKEN : {<#COMMENT_STUFF: ~["*","/"] | ~["*"]"/" | "*"~["/"]>}

TOKEN : {<ELSE   : "else">}
TOKEN : {<IF     : "if" >}
TOKEN : {<RETURN : "return">}
TOKEN : {<WHILE  : "while" >}

TOKEN : {<CHAR   : "char" >}
TOKEN : {<INT    : "int">}
TOKEN : {<VOID   : "void">}

TOKEN : {<IDENT  : <LETTER> (<LETTER> | <DIGIT>)*>}

TOKEN : {<INTEGER_CONSTANT : (<DIGIT>)+ | "\'\\n\'" | "\'"<CHARACTER>"\'">}

TOKEN : {<NOTEQ  : "!=">}
TOKEN : {<NOT    : "!">}
TOKEN : {<ANDAND : "&&">}
TOKEN : {<LPAREN : "(">}
TOKEN : {<RPAREN : ")">}
TOKEN : {<MUL    : "*">}
TOKEN : {<PLUS   : "+">}
TOKEN : {<COMMA  : ",">}
TOKEN : {<MINUS  : "-">}
TOKEN : {<DIV    : "/">}
TOKEN : {<SEMI   : ";">}
TOKEN : {<LTEQ   : "<=">}
TOKEN : {<LT     : "<">}
TOKEN : {<EQEQ   : "==">}
TOKEN : {<EQ     : "=">}
TOKEN : {<GTEQ   : ">=">}
TOKEN : {<GT     : ">">}
TOKEN : {<LBRACK : "[">}
TOKEN : {<RBRACK : "]">}
TOKEN : {<LBRACE : "{">}
TOKEN : {<RBRACE : "}">}

SKIP : {<LINE_COMMENT: "//" (~["\n"])* "\n">}
SKIP : {<LAST_LINE_COMMENT: "//" (~["\n"])* >}

SKIP : {<BLOCK_COMMENT: "/*" ("/")* (<COMMENT_STUFF>)* ("*")* "*/">}

SKIP : {<BLANK: [" ","\n","\r","\f","\t"]>}

TOKEN : {<UNTERMINATED_COMMENT: "/*" ("/")* (<COMMENT_STUFF>)* ("*")*>}
TOKEN : {<INVALID_CHAR: "'" <CHARACTER> (<CHARACTER>)+ "'">}
TOKEN : {<ANY: ~[]>}



void program ():
{
}
{
   { System.out.println("program"); }
   topdec_list()
}

void topdec_list():
{
}
{
   { System.out.println("topdec_list"); }
    topdec() topdec_list()
    |
    ( { } ) 
}

void topdec():
{
}
{
   { System.out.println("topdec"); }
    /*
    vardec() <SEMI>
    |
    funtype() <IDENT> <LPAREN> formals() <RPAREN> funbody()
    */
    
    /*
    (scalardec() | arraydec()) <SEMI>
    |
    (typename() | <VOID>) <IDENT> <LPAREN> formals() <RPAREN> funbody()
    */

    /*
    (typename() <IDENT> | typename() <IDENT> <LBRACK> <INTEGER_CONSTANT> <RBRACK>) <SEMI>
    |
    (typename() | <VOID>) <IDENT> <LPAREN> formals() <RPAREN> funbody()
    */

    /*
    typename() <IDENT> <SEMI>
    |
    typename() <IDENT> <LBRACK> <INTEGER_CONSTANT> <RBRACK> <SEMI>
    |
    typename() <IDENT> <LPAREN> formals() <RPAREN> funbody()
    |
    <VOID> <IDENT> <LPAREN> formals() <RPAREN> funbody()
    */

    typename() <IDENT>
    (
        <SEMI>
        |
        <LBRACK> <INTEGER_CONSTANT> <RBRACK> <SEMI>
        |
        <LPAREN> formals() <RPAREN> funbody()
    )
    |
    <VOID> <IDENT> <LPAREN> formals() <RPAREN> funbody()
    
}

void vardec():
{
}
{
   { System.out.println("vardec"); }
    /*
    scalardec()
    |
    arraydec()
    */
    
    /*
    typename() <IDENT>
    |
    typename() <IDENT> <LBRACK> <INTEGER_CONSTANT> <RBRACK>
    */

    typename() <IDENT>
    (
        <LBRACK> <INTEGER_CONSTANT> <RBRACK>
        |
        {}
    )

}

void scalardec():
{
}
{
   { System.out.println("scalardec"); }
    typename() <IDENT>
}

void arraydec():
{
}
{
   { System.out.println("arraydec"); }
    typename() <IDENT> <LBRACK> <INTEGER_CONSTANT> <RBRACK>
}

void typename():
{
}
{
   { System.out.println("typename"); }
    <INT> | <CHAR>
}

void funtype():
{
}
{
   { System.out.println("funtype"); }
    typename()
    |
    <VOID>
}

void funbody():
{
}
{
   { System.out.println("funbody"); }
    <LBRACE> locals() stmts() <RBRACE>
    |
    <SEMI>
}

void formals():
{
}
{
   { System.out.println("formals"); }
    <VOID>
    |
    formal_list()
}

void formal_list():
{
}
{
   { System.out.println("formal_list"); }
    /*
    formal_dec() 
    |
    formal_dec() <COMMA> formal_list()
    */

    formal_dec()
    (
        <COMMA> formal_list()
	|
	{}
    )
    
}

void formal_dec():
{
}
{
   { System.out.println("formal_dec"); }
    /*
    scalardec()
    |
    typename() <IDENT> <LBRACK> <RBRACK>
    */
    
    /*
    typename() <IDENT>
    |
    typename() <IDENT> <LBRACK> <RBRACK>
    */
    
    typename() <IDENT>
    (
        <IDENT> <LBRACK> <RBRACK>
        |
        {}
    )
    
}


void locals():
{
}
{
   { System.out.println("locals"); }
    vardec() <SEMI> locals()
    |
    {}
}

void stmts():
{
}
{
   { System.out.println("stmts"); }
    stmt() stmts()
    |
    {}
}

void stmt():
{
}
{
   { System.out.println("stmt"); }
    /*
    expr() <SEMI> 
    |    
    <RETURN> expr() <SEMI>
    |
    <RETURN> <SEMI>
    |
    <WHILE> condition() stmt()
    |
    <IF> condition() stmt() else_part()
    |
    <LBRACE> stmts() <RBRACE>
    |
    <SEMI>
    */

    expr() <SEMI> 
    |
    <RETURN>
    (
        expr() <SEMI>
        |
        <SEMI>
    )
    |
    <WHILE> {System.out.println("while()");} condition() {System.out.println("*stmt()*");} stmt()
    |
    <IF> condition() stmt() else_part()
    |
    <LBRACE> stmts() <RBRACE>
    |
    <SEMI>       
}

void else_part():
{
}
{
   { System.out.println("else_part"); }
    <ELSE> stmt()
    |
    {}
}

void condition():
{
}
{
   { System.out.println("condition"); }
    <LPAREN> expr() <RPAREN>
}


void basic_expr():
{
}
{
   { System.out.println("basic_expr"); }
    /*
    <INTEGER_CONSTANT>
    |
    <IDENT>
    |
    <IDENT> <LBRACK> expr() <RBRACK>
    |
    <IDENT> <LPAREN> actuals() <RPAREN>
    |
    <LPAREN> expr() <RPAREN>
    */

    <INTEGER_CONSTANT>
    |
    <IDENT>
    (
        <LBRACK> expr() <RBRACK>
        |
        <LPAREN> actuals() <RPAREN>
        |
        {}
    )
    |
    <LPAREN> expr() <RPAREN>    
}

void unary_expr():
{
}
{
   { System.out.println("unary_expr"); }
    unop() unary_expr()
    |
    basic_expr()
    
}

void multiplicative_expr():
{
}
{
   { System.out.println("multiplicative_expr"); }
    unary_expr() multiplicative_expr_h()
}

void multiplicative_expr_h():
{
}
{
   { System.out.println("multiplicative_expr_h"); }
    mulop() unary_expr() multiplicative_expr_h()
    |
    {}
}

void additive_expr():
{
}
{
   { System.out.println("additive_expr"); }
    multiplicative_expr() additive_expr_h()
}


void additive_expr_h():
{
}
{
   { System.out.println("additive_expr_h"); }
    addop() multiplicative_expr() additive_expr_h()
    |
    {}
}

void relational_expr():
{
}
{
   { System.out.println("relationa_expr"); }
    additive_expr() relational_expr_h()
}

void relational_expr_h():
{
}
{
   { System.out.println("relational_expr_h"); }
    relop() additive_expr() relational_expr_h()
    |
    {}
}

void equality_expr():
{
}
{
   { System.out.println("equality_expr"); }
    relational_expr() equality_expr_h()
}

void equality_expr_h():
{
}
{
   { System.out.println("equality_expr_h"); }
    equalop() relational_expr() equality_expr_h()
    |
    {}
}

void and_expr():
{
}
{    
   { System.out.println("and_exp"); }
    equality_expr() and_expr_h()
}

void and_expr_h():
{
}
{
   { System.out.println("and_expr_h"); }
    <ANDAND> equality_expr() and_expr_h() 
    |
    {}
}

void expr():
{
}
{
   { System.out.println("expr"); }
    /*
    and_expr() <EQ> expr()
    |
    and_expr()       
    */

    and_expr()
    (
     <EQ> expr()
     |
     {}
    )
}

void unop():
{
}
{
   { System.out.println("unop"); }
    <MINUS>
    |
    <NOT>
}

void mulop():
{
}
{
   { System.out.println("mulop"); }
    <MUL>
    |
    <DIV>
}

void addop():
{
}
{
   { System.out.println("addop"); }
    <PLUS>
    |
    <MINUS>    
}

void relop():
{
}
{
   { System.out.println("relop"); }
    <LT>
    |
    <GT>
    |
    <LTEQ>
    |
    <GTEQ>
}


void equalop():
{
}
{
   { System.out.println("equalop"); }
    <NOTEQ>
    |
    <EQEQ>
}

void actuals():
{
}
{
   { System.out.println("actuals"); }
    expr_list()
    |
    {}
}

void expr_list():
{
}
{
   { System.out.println("expr_list"); }
    /*expr()
    |
    expr() <COMMA> expr_list()*/
    
    expr()
    (
        <COMMA> expr_list()
        |
	{}
    )
}


PARSER_BEGIN(UcParser) 
  
import java.util.*;
import java.io.*;  

class UcParser {
  public static void main(String[] arg) 
  throws ParseException, IOException {
    if (arg.length != 1) {
        System.out.println("Usage: UcParse <input file name>");
        System.exit(0);
    }

    InputStream is = new FileInputStream(arg[0]);

    UcParser parser = new UcParser(is);
    program();
    System.out.println("parsed");
    //Node tree = program();
    //tree.print("");

  }
}

PARSER_END(UcParser)


// More tokens here!
TOKEN : {<#DIGIT : ["0"-"9"]>}
TOKEN : {<#LETTER: ["a"-"z","A"-"Z","_"]>}
TOKEN : {<#CHARACTER: [" ","!","\"","#","$","%","&","'","(",")","*","+",",","-",".","/","0"-"9",":",";","<","=",">","?","@","A"-"Z","[","\\","]","^","_","`","a"-"z","{","|","}","~"]>}
TOKEN : {<#COMMENT_STUFF: ~["*","/"] | ~["*"]"/" | "*"~["/"]>}

TOKEN : {<ELSE   : "else">}
TOKEN : {<IF     : "if" >}
TOKEN : {<RETURN : "return">}
TOKEN : {<WHILE  : "while" >}

TOKEN : {<CHAR   : "char" >}
TOKEN : {<INT    : "int">}
TOKEN : {<VOID   : "void">}

TOKEN : {<IDENT  : <LETTER> (<LETTER> | <DIGIT>)*>}

TOKEN : {<INTEGER_CONSTANT : (<DIGIT>)+ | "\'\\n\'" | "\'"<CHARACTER>"\'">}

TOKEN : {<NOTEQ  : "!=">}
TOKEN : {<NOT    : "!">}
TOKEN : {<ANDAND : "&&">}
TOKEN : {<LPAREN : "(">}
TOKEN : {<RPAREN : ")">}
TOKEN : {<MUL    : "*">}
TOKEN : {<PLUS   : "+">}
TOKEN : {<COMMA  : ",">}
TOKEN : {<MINUS  : "-">}
TOKEN : {<DIV    : "/">}
TOKEN : {<SEMI   : ";">}
TOKEN : {<LTEQ   : "<=">}
TOKEN : {<LT     : "<">}
TOKEN : {<EQEQ   : "==">}
TOKEN : {<EQ     : "=">}
TOKEN : {<GTEQ   : ">=">}
TOKEN : {<GT     : ">">}
TOKEN : {<LBRACK : "[">}
TOKEN : {<RBRACK : "]">}
TOKEN : {<LBRACE : "{">}
TOKEN : {<RBRACE : "}">}

SKIP : {<LINE_COMMENT: "//" (~["\n"])* "\n">}
SKIP : {<LAST_LINE_COMMENT: "//" (~["\n"])* >}

SKIP : {<BLOCK_COMMENT: "/*" ("/")* (<COMMENT_STUFF>)* ("*")* "*/">}

SKIP : {<BLANK: [" ","\n","\r","\f","\t"]>}

TOKEN : {<UNTERMINATED_COMMENT: "/*" ("/")* (<COMMENT_STUFF>)* ("*")*>}
TOKEN : {<INVALID_CHAR: "'" <CHARACTER> (<CHARACTER>)+ "'">}
TOKEN : {<ANY: ~[]>}



void program ():
{
}
{
   { System.out.println("program"); }
   topdec_list()
}

void topdec_list():
{
}
{
   { System.out.println("topdec_list"); }
    topdec() topdec_list()
    |
    ( { } ) 
}

void topdec():
{
}
{
   { System.out.println("topdec"); }
    /*
    vardec() <SEMI>
    |
    funtype() <IDENT> <LPAREN> formals() <RPAREN> funbody()
    */
    
    /*
    (scalardec() | arraydec()) <SEMI>
    |
    (typename() | <VOID>) <IDENT> <LPAREN> formals() <RPAREN> funbody()
    */

    /*
    (typename() <IDENT> | typename() <IDENT> <LBRACK> <INTEGER_CONSTANT> <RBRACK>) <SEMI>
    |
    (typename() | <VOID>) <IDENT> <LPAREN> formals() <RPAREN> funbody()
    */

    /*
    typename() <IDENT> <SEMI>
    |
    typename() <IDENT> <LBRACK> <INTEGER_CONSTANT> <RBRACK> <SEMI>
    |
    typename() <IDENT> <LPAREN> formals() <RPAREN> funbody()
    |
    <VOID> <IDENT> <LPAREN> formals() <RPAREN> funbody()
    */

    typename() <IDENT>
    (
        <SEMI>
        |
        <LBRACK> <INTEGER_CONSTANT> <RBRACK> <SEMI>
        |
        <LPAREN> formals() <RPAREN> funbody()
    )
    |
    <VOID> <IDENT> <LPAREN> formals() <RPAREN> funbody()
    
}

void vardec():
{
}
{
   { System.out.println("vardec"); }
    /*
    scalardec()
    |
    arraydec()
    */
    
    /*
    typename() <IDENT>
    |
    typename() <IDENT> <LBRACK> <INTEGER_CONSTANT> <RBRACK>
    */

    typename() <IDENT>
    (
        <LBRACK> <INTEGER_CONSTANT> <RBRACK>
        |
        {}
    )

}

void scalardec():
{
}
{
   { System.out.println("scalardec"); }
    typename() <IDENT>
}

void arraydec():
{
}
{
   { System.out.println("arraydec"); }
    typename() <IDENT> <LBRACK> <INTEGER_CONSTANT> <RBRACK>
}

void typename():
{
}
{
   { System.out.println("typename"); }
    <INT> | <CHAR>
}

void funtype():
{
}
{
   { System.out.println("funtype"); }
    typename()
    |
    <VOID>
}

void funbody():
{
}
{
   { System.out.println("funbody"); }
    <LBRACE> locals() stmts() <RBRACE>
    |
    <SEMI>
}

void formals():
{
}
{
   { System.out.println("formals"); }
    <VOID>
    |
    formal_list()
}

void formal_list():
{
}
{
   { System.out.println("formal_list"); }
    /*
    formal_dec() 
    |
    formal_dec() <COMMA> formal_list()
    */

    formal_dec()
    (
        <COMMA> formal_list()
	|
	{}
    )
    
}

void formal_dec():
{
}
{
   { System.out.println("formal_dec"); }
    /*
    scalardec()
    |
    typename() <IDENT> <LBRACK> <RBRACK>
    */
    
    /*
    typename() <IDENT>
    |
    typename() <IDENT> <LBRACK> <RBRACK>
    */
    
    typename() <IDENT>
    (
        <IDENT> <LBRACK> <RBRACK>
        |
        {}
    )
    
}


void locals():
{
}
{
   { System.out.println("locals"); }
    vardec() <SEMI> locals()
    |
    {}
}

void stmts():
{
}
{
   { System.out.println("stmts"); }
    stmt() stmts()
    |
    {}
}

void stmt():
{
}
{
   { System.out.println("stmt"); }
    /*
    expr() <SEMI> 
    |    
    <RETURN> expr() <SEMI>
    |
    <RETURN> <SEMI>
    |
    <WHILE> condition() stmt()
    |
    <IF> condition() stmt() else_part()
    |
    <LBRACE> stmts() <RBRACE>
    |
    <SEMI>
    */

    expr() <SEMI> 
    |
    <RETURN>
    (
        expr() <SEMI>
        |
        <SEMI>
    )
    |
    <WHILE> {System.out.println("while()");} condition() {System.out.println("*stmt()*");} stmt()
    |
    <IF> condition() stmt() else_part()
    |
    <LBRACE> stmts() <RBRACE>
    |
    <SEMI>       
}

void else_part():
{
}
{
   { System.out.println("else_part"); }
    <ELSE> stmt()
    |
    {}
}

void condition():
{
}
{
   { System.out.println("condition"); }
    <LPAREN> expr() <RPAREN>
}


void basic_expr():
{
}
{
   { System.out.println("basic_expr"); }
    /*
    <INTEGER_CONSTANT>
    |
    <IDENT>
    |
    <IDENT> <LBRACK> expr() <RBRACK>
    |
    <IDENT> <LPAREN> actuals() <RPAREN>
    |
    <LPAREN> expr() <RPAREN>
    */

    <INTEGER_CONSTANT>
    |
    <IDENT>
    (
        <LBRACK> expr() <RBRACK>
        |
        <LPAREN> actuals() <RPAREN>
        |
        {}
    )
    |
    <LPAREN> expr() <RPAREN>    
}

void unary_expr():
{
}
{
   { System.out.println("unary_expr"); }
    unop() unary_expr()
    |
    basic_expr()
    
}

void multiplicative_expr():
{
}
{
   { System.out.println("multiplicative_expr"); }
    unary_expr() multiplicative_expr_h()
}

void multiplicative_expr_h():
{
}
{
   { System.out.println("multiplicative_expr_h"); }
    mulop() unary_expr() multiplicative_expr_h()
    |
    {}
}

void additive_expr():
{
}
{
   { System.out.println("additive_expr"); }
    multiplicative_expr() additive_expr_h()
}


void additive_expr_h():
{
}
{
   { System.out.println("additive_expr_h"); }
    addop() multiplicative_expr() additive_expr_h()
    |
    {}
}

void relational_expr():
{
}
{
   { System.out.println("relationa_expr"); }
    additive_expr() relational_expr_h()
}

void relational_expr_h():
{
}
{
   { System.out.println("relational_expr_h"); }
    relop() additive_expr() relational_expr_h()
    |
    {}
}

void equality_expr():
{
}
{
   { System.out.println("equality_expr"); }
    relational_expr() equality_expr_h()
}

void equality_expr_h():
{
}
{
   { System.out.println("equality_expr_h"); }
    equalop() relational_expr() equality_expr_h()
    |
    {}
}

void and_expr():
{
}
{    
   { System.out.println("and_exp"); }
    equality_expr() and_expr_h()
}

void and_expr_h():
{
}
{
   { System.out.println("and_expr_h"); }
    <ANDAND> equality_expr() and_expr_h() 
    |
    {}
}

void expr():
{
}
{
   { System.out.println("expr"); }
    /*
    and_expr() <EQ> expr()
    |
    and_expr()       
    */

    and_expr()
    (
     <EQ> expr()
     |
     {}
    )
}

void unop():
{
}
{
   { System.out.println("unop"); }
    <MINUS>
    |
    <NOT>
}

void mulop():
{
}
{
   { System.out.println("mulop"); }
    <MUL>
    |
    <DIV>
}

void addop():
{
}
{
   { System.out.println("addop"); }
    <PLUS>
    |
    <MINUS>    
}

void relop():
{
}
{
   { System.out.println("relop"); }
    <LT>
    |
    <GT>
    |
    <LTEQ>
    |
    <GTEQ>
}


void equalop():
{
}
{
   { System.out.println("equalop"); }
    <NOTEQ>
    |
    <EQEQ>
}

void actuals():
{
}
{
   { System.out.println("actuals"); }
    expr_list()
    |
    {}
}

void expr_list():
{
}
{
   { System.out.println("expr_list"); }
    /*expr()
    |
    expr() <COMMA> expr_list()*/
    
    expr()
    (
        <COMMA> expr_list()
        |
	{}
    )
}
